home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 051-075 / disk_056 / mcad / mp / source / plot.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  8KB  |  304 lines

  1. #include "struct.h"
  2. #include "plot.h"
  3. #include <graphics/gfxmacros.h>
  4.  
  5. extern int debug;
  6. extern FFP fround();
  7.  
  8. /**********************/
  9. void GetDataLimits(Pict)
  10. struct Pict *Pict;
  11. {
  12.    short i;
  13.    FFP *x, *y, *e;
  14.    struct Plot *Plot;
  15.    FFP xmin, xmax, ymin, ymax;
  16.  
  17.    xmin = (ymin = FFPLARGE);
  18.    xmax = (ymax = -FFPLARGE);
  19.    
  20.    Plot = Pict->Plot;
  21.    while (Plot) {
  22.       if (Plot->Enabled) {
  23.          i = 0; x = Plot->x; y = Plot->y;
  24.          if (Pict->ShowErr) e = Plot->e;
  25.          while (i++ < Plot->NPts) {
  26.             xmax = max(*x,xmax);
  27.             xmin = min(*x,xmin);
  28.             x++;
  29.             if (Pict->ShowErr) {
  30.                ymax = max((*y + *e), ymax);
  31.                ymin = min((*y - *e), ymin);
  32.                y++; e++;
  33.             }
  34.             else {
  35.                ymax = max(*y,ymax);
  36.                ymin = min(*y,ymin);
  37.                y++;
  38.             }
  39.          }
  40.       }
  41.       Plot = Plot->NextPlot;
  42.    }
  43.  
  44.    if (!Pict->XRegionLock)
  45.       {Pict->CurrReg->XMax = xmax; Pict->CurrReg->XMin = xmin;}
  46.    if (!Pict->YRegionLock)
  47.       {Pict->CurrReg->YMax = ymax; Pict->CurrReg->YMin = ymin;}
  48. }
  49.  
  50.  
  51. /*****************************************/
  52. void AdjustForTics(dmin, dmax, ntics, tics)
  53. FFP *dmin, *dmax, *tics;
  54. short ntics;
  55. {
  56.    FFP tmp, fract, f_ntics;
  57.    short i;
  58.    
  59.    f_ntics = (FFP)(ntics);
  60.    fract = (FFP)(ntics+1) / f_ntics;
  61.    
  62.    /*** adjust data limits to make "nice" numbers for tic marks ***/
  63.    tmp = *dmin - (*dmax - *dmin) / 5;
  64.    *dmin = fround( *dmin, DOWN, tmp);
  65.    tmp = (*dmax - *dmin) / f_ntics;
  66.    tmp = fround( tmp, UP, (tmp * fract) );
  67.    *dmax = *dmin + tmp * f_ntics;
  68.  
  69.    tics[0] = *dmin;
  70.    if (debug) printf("... tic[0]=%f\n", tics[0]);
  71.    for (i=1; i<ntics; i++) {
  72.       tics[i] = tics[i-1] + tmp;
  73.       if (debug) printf("... tic[%d]=%f\n", i, tics[i]);
  74.    }
  75. }
  76.  
  77.  
  78. /**************/
  79. void Scale(Pict)
  80. struct Pict *Pict;
  81. {
  82.    struct Plot *Plot;
  83.    struct PlotRegion *Reg;
  84.    struct Tics *Tics;
  85.    register short i, *xp, *yp;
  86.    register FFP *x, *y, xmin, ymin, xscale, yscale;
  87.    short *ep, err, err_sav = TRUE;
  88.    FFP *e, xmax, ymax;
  89.    
  90.    if (debug) printf("Scale: entry\n");
  91.    Reg = Pict->CurrReg;
  92.    xmin = Reg->XMin; xmax = Reg->XMax;
  93.    ymin = Reg->YMin; ymax = Reg->YMax;
  94.  
  95.    if (FFPSAME(xmax,xmin))
  96.       {printf("Scale: xmax = xmin, xscale := 0.\n"); xscale = (FFP)0;}
  97.    else 
  98.       Pict->XScale = xscale = (FFP)(XMAXP-XMINP) / (xmax - xmin);
  99.    if (FFPSAME(ymax,ymin))
  100.       {printf("Scale: ymax = ymin, yscale := 0.\n"); yscale = (FFP)0;}
  101.    else 
  102.       Pict->YScale = yscale = (FFP)(YMAXP-YMINP) / (ymax - ymin);
  103.  
  104. #define NEW_X_REGION ( !FFPSAME(Reg->XMin,xmin) || !FFPSAME(Reg->XMax,xmax) )
  105. #define NEW_Y_REGION ( !FFPSAME(Reg->YMin,ymin) || !FFPSAME(Reg->YMax,ymax) )
  106.  
  107.    /* DATA */
  108.    Plot = Pict->Plot;
  109.    err = Pict->ShowErr;
  110.    while (Plot) {
  111.       if (Plot->Enabled) {
  112.          Reg = Plot->Reg;
  113.  
  114.          if (NEW_X_REGION) {
  115.             x = Plot->x; xp = Plot->xp;
  116.             for (i = 0; i < Plot->NPts; i++) {
  117.                *xp++ = XMINP + (short)((*x++ - xmin) * xscale);
  118.                if (debug) printf("*xp=%d\n", *(xp-1));
  119.             }
  120.             Reg->XMin = xmin; Reg->XMax = xmax;
  121.          }
  122.  
  123.          if ( (NEW_Y_REGION) || (err_sav!=err) ) {
  124.             y = Plot->y; yp = Plot->yp; e = Plot->e; ep = Plot->ep;
  125.             for (i = 0; i < Plot->NPts; i++) {
  126.                *yp++ = YMINP + (short)((*y++ - ymin) * yscale);
  127.                if (debug) printf("*yp=%d", *(yp-1));
  128.                if (err) {
  129.                   *ep++ = (short)(*e++ * yscale);
  130.                   if (debug) printf(", *ep=%d", *(ep-1));
  131.                }
  132.                if (debug) printf("\n");
  133.             }
  134.             Reg->YMin = ymin; Reg->YMax = ymax;
  135.          }
  136.  
  137.       }
  138.       Plot = Plot->NextPlot;
  139.    }
  140.    err_sav = err;
  141.  
  142.    /* TICS */
  143.    Tics = Pict->Tics;
  144.    for (i=0; i < Tics->NX; i++)
  145.       Tics->xp[i] = XMINP + (short)((Tics->x[i] - xmin) * xscale);
  146.  
  147.    for (i=0; i < Tics->NY; i++)
  148.       Tics->yp[i] = YMINP + (short)((Tics->y[i] - ymin) * yscale);
  149.  
  150.    if (debug) printf("Scale: entry\n");
  151. }
  152.  
  153.  
  154. /**********************/
  155. void DrawAxes(Tics,Grid)
  156. struct Tics *Tics; short Grid;
  157. {
  158.    short *xp, *yp, n, tmpx, tmpy, i;
  159.    char tmpstr[20];
  160.       
  161.    /*** DRAW BORDER ***/
  162.    SetAPen(rp,2); SetOPen(rp,1);
  163.    PRectFill(XMINP-1,YMINP-1,XMAXP+1,YMAXP+1);
  164.    PRectFill(XMINP,YMINP,XMAXP,YMAXP);
  165.  
  166.    /*** DRAW TICS/GRID ***/
  167.    SetAPen(rp,3);
  168.    xp=Tics->xp; yp=Tics->yp;
  169.    if (Grid) SetRGB4(vp,3,0,15,15);
  170.    for (i=1; i < Tics->NX; i++) {
  171.       if (Grid) {
  172.          PMove(xp[i],YMINP+1); PDraw(xp[i],YMAXP-1);
  173.       }
  174.       else {
  175.          PMove(xp[i],YMINP+1); PDraw(xp[i],YMINP+X_TIC_SIZE);
  176.          PMove(xp[i],YMAXP-1); PDraw(xp[i],YMAXP-X_TIC_SIZE);
  177.       }
  178.    }
  179.    for (i=1; i < Tics->NY; i++) {
  180.       if (Grid) {
  181.          PMove(XMINP+1,yp[i]); PDraw(XMAXP-1,yp[i]);
  182.       }
  183.       else {
  184.          PMove(XMINP+1,yp[i]); PDraw(XMINP+Y_TIC_SIZE,yp[i]);
  185.          PMove(XMAXP-1,yp[i]); PDraw(XMAXP-Y_TIC_SIZE,yp[i]);
  186.       }
  187.    }
  188.  
  189.    /*** PRINT TIC VALUES ***/
  190.    SetAPen(rp,1);
  191.    for (i=0; i < Tics->NX; i++) {
  192.       n = sprintf(&tmpstr, "%-.4f", Tics->x[i]);
  193.       n = min(n, 7);
  194.       while (tmpstr[n-1] == '0') n--;
  195.       tmpx = Tics->xp[i] - ((n/2) - (FFP)1/2) * CHARWIDTH;
  196.       tmpy = max(0, YMINP-2*CHARHEIGHT);
  197.       PMove(tmpx, tmpy); Text(rp,tmpstr,n);
  198.    }
  199.    for (i=0; i < Tics->NY; i++) {
  200.       n = sprintf(&tmpstr, "%-.4f", Tics->y[i]);
  201.       n = min( n, (LMARGIN/CHARWIDTH)-1 );
  202.       while (tmpstr[n-1] == '0') n--;
  203.       tmpx = max(0, XMINP-(n+1)*CHARWIDTH);
  204.       PMove(tmpx, Tics->yp[i]-CHARHEIGHT/2); Text(rp,tmpstr,n);
  205.    }
  206. }
  207.  
  208.  
  209. /*****************/
  210. void DrawPlot(Pict)
  211. struct Pict *Pict;
  212. {
  213.    struct Plot *Plot;
  214.    short *x, *y, *e, n, m, i;
  215.  
  216.    Plot = Pict->Plot;
  217.    
  218.    while (Plot) {
  219.       if (Plot->Enabled) {
  220.          SetAPen(rp, Plot->Color);
  221.   
  222.          /* PLOT POINTS */
  223.          if (Plot->PointSize != 0) {
  224.             n = Plot->PointSize;
  225.             if (abs(n) > 2) {m = (abs(n)/2)-1; SetOPen(rp, Plot->Color);}
  226.             x = Plot->xp; y = Plot->yp;
  227.             for (i=0; i<Plot->NPts; i++, x++, y++) {
  228.                switch (abs(n)) {
  229.                case 0: break;
  230.                case 1: PWritePixel(*x, *y); break;
  231.                case 2: PWritePixel(*x, *y); PWritePixel(*x, *y+1); break;
  232.                case 3: PRectFill(*x, *y, *x+1, *y+1); break;
  233.                default: PRectFill(*x-m, *y-m, *x+m, *y+m); break;
  234.                }
  235.             }
  236.          }
  237.    
  238.          /* PLOT LINES */
  239.          if (Plot->PointSize <= 0) {
  240.             PMove(*Plot->xp, *Plot->yp);
  241.             x = &(Plot->xp[1]); y = &(Plot->yp[1]);
  242.             for (i=1; i<Plot->NPts; i++, x++, y++) PDraw(*x, *y);
  243.          }
  244.          
  245.          /* PLOT ERROR BARS */
  246.          if (Pict->ShowErr) {
  247.             x = Plot->xp; y = Plot->yp; e = Plot->ep;
  248.             for (i=0; i < Plot->NPts; i++, x++, y++, e++) {
  249.                PMove(*x, *y - *e); PDraw(*x, *y + *e);
  250.             }
  251.          }
  252.  
  253.       }
  254.       Plot = Plot->NextPlot;
  255.    }
  256. }
  257.  
  258.  
  259. /*************************************************************/
  260. extern int CheckUser();
  261. extern int GetHowTo();
  262.  
  263. void plot(Pict)
  264. struct Pict *Pict;
  265. {
  266.    struct PlotRegion *Reg;
  267.    struct Tics *Tics;
  268.    int req = GETHOWTO;
  269.  
  270.    Tics = Pict->Tics;
  271.    do {
  272.       switch(req) {
  273.       case GETHOWTO: GetHowTo(Pict); /* fall thru */
  274.       case GETDATALIMITS: GetDataLimits(Pict);
  275.       case REPLOT:
  276.       default: ;
  277.       }
  278.       Reg = Pict->CurrReg;
  279.       if (!Pict->XRegionLock)
  280.          AdjustForTics(&Reg->XMin, &Reg->XMax, Tics->NX, Tics->x);
  281.       if (!Pict->YRegionLock)
  282.          AdjustForTics(&Reg->YMin, &Reg->YMax, Tics->NY, Tics->y);
  283.       
  284.       Scale(Pict);
  285.       InitWind();
  286.       if (Pict->Axes) DrawAxes(Pict->Tics,Pict->Grid);
  287.       DrawPlot(Pict);
  288.       req = CheckUser(Pict);
  289.    } while (req != QUIT);
  290. }
  291.  
  292.  
  293. /***************************/
  294. void PToU(Pict, xp, yp, x, y)
  295. struct Pict *Pict;
  296. short xp, yp;
  297. FFP *x, *y;
  298. {
  299.    if (debug) printf("PToU: entry, xp=%d, yp=%d\n", xp, yp);
  300.    *x = Pict->CurrReg->XMin + (FFP)(xp-XMINP) / Pict->XScale;
  301.    *y = Pict->CurrReg->YMin + (FFP)(yp-YMINP) / Pict->YScale;
  302.    if (debug) printf("PToU: exit, *x=%f, *y=%f\n", *x, *y);
  303. }
  304.